/*
  功能： 完成一些费时或不需要等待结果的数据库操作。
        读取协议表格，获得协议，存储在成员变量mapHeadProtocal中。可以存储多个协议.
        如果程序中需要立即返回结果，则在主线程中，直接调用该类的函数，而不是用信号与槽机制。
  */

#ifndef DBOINTHREAD_H
#define DBOINTHREAD_H

#include <QObject>
#include <QMap>
#include <QMutex>
#include <QHostAddress>
#include "protocal.h"

class QSqlQuery;
class ProtocolConversion;
class WeatherStation;
class QTimer;
class DataMining;

class DBOInThread : public QObject
{
    Q_OBJECT
public:
    DBOInThread(QObject* parent=0);

    ~DBOInThread();
    bool    insertLog(QString issue);
    //读取数据库的协议表，将相应内容存储在数据变量
    //protocalHead参数是指网关接口协议的头，十六进制，如“aa55”.
    bool readProtocolTable(QByteArray protocalHead);
    //建立一个连接
    bool createConnection(const QString  dataBase,const QString  host,
        const QString  user, const QString  passWord,const QString connectionName);

signals:
     void sigDataConvertedForGW(QByteArray GWData,QString appIP,quint16 appPort,
                                qint64 nodeMacAddr,QByteArray baSNBase10);
     void sigCmdAckToApp(QByteArray dataGram,QString appIP,quint16 appPort);
     void sigErrorInfo(QString errorStr);

     bool sigAddVideoSource(QString sourceIP,quint16 sourcePort,qint64 nodeMacAddr,
              quint8 sensorID);

     QByteArray sigSendONSMesg(QString paraURI_ObjName,QString paraURI_ObjType,
          QString paraURI_ObjOwner,QString paraURI_ObjLocation,
          QString paraServiceType,QString paraID,
          bool paraIsGW=true,QString paraPWD="");

     void sigAddNode(qint64  nodeMacAddr,QByteArray nodeName);
     void sigPinQueryFromNodeDone(QByteArray reply,qint64 nodeMacAddr);
     void sigDeleteNode(qint64  nodeMacAddr,QByteArray nodeName);


public slots:
     QByteArray slotConvertProtocol(QByteArray appData,
                    QString hostIP,quint16 port,qint64 nodeMAcAddr);

     QByteArray slotCmdAck(QByteArray packet);
     //将视频数据存储到数据库
     void slotStoreVideo(QByteArray data,qint64  nodeMacAddr,quint8 SN,QList <QString> *tableNameList,
           QString *tableNamePrefix,QList <qint64>  *newMacList);

     //注册一个节点。在数据库的nodeAddressMap中，插入相应的数据。在插入前，会先检查是否已经有数据了
     void slotRegNode(qint64  nodeMacAddr,QByteArray nodeName,qint8 nodeOnWork,QByteArray nodeV4IP,
             quint16 nodeV4Port,QByteArray nodeType,QByteArray protocHead,qint8 nodeOccupied);

     void slotUnRegNode(qint64  nodeSubMacAddr); //低7字节地址

     //注册一个传感器，在数据库的nodesensorMap中插入相应的数据。在插入前，会先检查是否已经有数据了
     void slotRegSensorMore(qint64 nodeMacAddr,qint16 sensorID,qint8 sensorOnWork,qint8 dataLen,
                        QByteArray expre);
     //dataLen和expre将使用typemap表格中的默认值。会调用slotRegSensorMore。
     void slotRegSensor(qint64 nodeMacAddr,qint16 sensorID,qint8 sensorOnWork);
     void slotUnRegSensor(qint64 nodeMacAddr,qint16 sensorID,qint8 sensorOnWork);

     void slotTimerEventDBConnect();

     void slotTestSignal(); //用于调试程序
     //处理节点发送的查询信息
     void slotPinQuery(qint64 nodeMacAddr);

     void slotRemoveOneInControllingMacList(QString macStr);

     void slotConnectDB();


private:
     bool    createMultiTable(qint64 nodeMacAddr,quint8 sensorID,QList <QString> *tableNameList,
                              QString *tableNamePrefix);
     void initTables();  //程序启动后，对数据库的几个表格进行初始化处理

     QTimer *timerForDBConnect;

public:
    ProtocolConversion *protConv; //在createconnection函数中构造
    QSqlQuery *qury;
    QString dboConnectionName;
    QMap <QString, Protocal> mapHeadProtocal;
    quint16 packetLen;  //数据包长度（bit数除以4）

    DataMining *dataMining;
    bool isConnected;

};

#endif // DBOINTHREAD_H
